package com.lhq.tag_tales.aspect;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lhq.tag_tales.annotation.CheckIsCurrentUser;
import com.lhq.tag_tales.common.ErrorCodeEnum;
import com.lhq.tag_tales.common.IsCurrentUserEnum;
import com.lhq.tag_tales.exception.BusinessException;
import com.lhq.tag_tales.mapper.TeamMapper;
import com.lhq.tag_tales.model.domain.Team;
import com.lhq.tag_tales.model.domain.User;
import com.lhq.tag_tales.model.domain.request.TeamAddRequest;
import com.lhq.tag_tales.model.domain.request.TeamUpdateRequest;
import com.lhq.tag_tales.service.UserService;
import com.lhq.tag_tales.utils.BeanUtilsCustom;
import com.lhq.tag_tales.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * AOP，判断是否是当前用户
 */
@Aspect
@Component
@Slf4j
public class CheckCurrentUser {
    @Resource
    private TeamMapper teamMapper;
    @Resource
    private UserService userService;

    /**
     * 切入点
     */
    @Pointcut("execution(public * com.lhq.tag_tales.service.impl.TeamServiceImpl.*(..))&& @annotation(com.lhq.tag_tales.annotation.CheckIsCurrentUser)")
    public void check() {
    }

    @Before("check()")
    public void checkInfo(JoinPoint joinPoint) throws IllegalAccessException {
        log.info("校验操作用户是否是当前用户");
        //获得方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //尝试获取方法上的CheckInfo注解
        CheckIsCurrentUser checkInfo = signature.getMethod().getAnnotation(CheckIsCurrentUser.class);
        if (checkInfo == null) {
            return;
        }
        //获取注解的值
        IsCurrentUserEnum value = checkInfo.value();
        if (value != IsCurrentUserEnum.CHECK) {
            return;
        }
        //获取类的类型
        Class<?> type = checkInfo.type();
        //获取方法参数
        Object[] args = joinPoint.getArgs();
        //使用UserUtils替代HttpServletRequest
        User currentUser = UserUtils.getCurrentUser();
        if (currentUser == null) {
            throw new BusinessException(ErrorCodeEnum.NO_LOGIN, "未登录");
        }
        //提前校验，当用户没有通过审核时不允许进行操作
        if (currentUser.getIsValid().equals(0)) {
            throw new BusinessException(ErrorCodeEnum.NO_AUTH, "账号未通过审核");
        }
        //team对象或者teamId
        Object teamOrTeamId = args[0];
        if (teamOrTeamId == null) {
            throw new BusinessException(ErrorCodeEnum.PARAMS_ERROR, "参数为空");
        }
        Long currentUserId = currentUser.getId();
        if (type.isInstance(teamOrTeamId)) {
            if (teamOrTeamId instanceof Long) {
                QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("id", teamOrTeamId);
                Team team = teamMapper.selectOne(queryWrapper);
                if (team == null) {
                    throw new BusinessException(ErrorCodeEnum.PARAMS_ERROR, "删除数据错误，数据不存在");
                }
                if (!team.getCreator().equals(currentUserId) && !userService.isAdmin(currentUser)) {
                    throw new BusinessException(ErrorCodeEnum.NO_AUTH, "无操作权限");
                }
            } else if (teamOrTeamId instanceof TeamAddRequest || teamOrTeamId instanceof TeamUpdateRequest) {
                Team team = new Team();
                BeanUtilsCustom.copyProperties(teamOrTeamId, team);
                //查询队伍的创建人
                Long creator = team.getCreator();
                if (!creator.equals(currentUserId) && !userService.isAdmin(currentUser)) {
                    throw new BusinessException(ErrorCodeEnum.NO_AUTH, "无操作权限");
                }
            } else {
                throw new BusinessException(ErrorCodeEnum.PARAMS_ERROR, "未知的参数类型");
            }
        } else {
            throw new BusinessException(ErrorCodeEnum.PARAMS_ERROR, "参数类型不匹配");
        }
    }
}
